package com.lry.util.rest;

import com.alibaba.fastjson.JSON;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * 请求包装
 *
 * @author ALI
 * @since 2022/9/28
 */
public class HttpRequestWrapper extends HttpServletRequestWrapper {

    private HttpServletRequest request;
    private Map<String, Object> params;
    private String body;

    public HttpRequestWrapper(HttpServletRequest request) {
        super(request);
        body = readBody(request);
        this.request = request;
        params = JSON.parseObject(body);
    }

    /**
     * 获取请求中的参数
     *
     * @return 参数（修改会同步）
     */
    public Map<String, Object> getParams() {
        return this.params;
    }

    /**
     * 设置参数对象
     *
     * @param params 参数（修改同步）
     */
    public void setParams(Map<String, Object> params) {
        this.params = params;
        this.body = JSON.toJSONString(this.params);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(JSON.toJSONBytes(params));
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    @Override
    public String getParameter(String name) {
        if ("GET".equals(request.getMethod())) {
            return request.getParameter(name);
        }
        Object obj = params.get(name);
        if (obj == null) {
            return null;
        }
        if (obj instanceof String[]) {
            String[] strArray = (String[]) obj;
            if (strArray.length > 0) {
                return strArray[0];
            } else {
                return null;
            }
        } else if (obj instanceof String) {
            return obj.toString();
        }
        return obj.toString();
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(params.keySet());
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8));
    }

    public String getBody() {
        return body;
    }

    public void setParam(String name, Object value) {
        if (value != null) {
            if (value instanceof String[]) {
                params.put(name, (String[]) value);
            } else if (value instanceof String) {
                params.put(name, new String[] {(String) value});
            } else {
                params.put(name, new String[] {String.valueOf(value)});
            }
        }
    }

    private String readBody(HttpServletRequest servletRequest) {
        BufferedReader reader = null;
        StringBuilder sb = new StringBuilder();
        try {
            reader = servletRequest.getReader();
            String str = null;
            while ((str = reader.readLine()) != null) {
                sb.append(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return sb.toString();
    }
}
